#include "Tools.h"

void FreeColNode(COL_NODE **pNode)
{
	COL_NODE *pNext;
	
	while (*pNode) 
	{
		pNext = (*pNode)->next;
		Tools_Free(pNode);
		*pNode = pNext;
	}
}

void FreeRowNode(ROW_NODE **pNode)
{
	ROW_NODE *pNext;
	while (*pNode) 
	{
		pNext = (*pNode)->next;
		FreeColNode(&(*pNode)->node);
		if ((*pNode)->buf) {
			Tools_Free(&(*pNode)->buf);
		}
		Tools_Free(pNode);
		*pNode = pNext;
	}
}

COL_NODE* StringSplit(char *pSrc, char c)
{
	COL_NODE *pNode = NULL;
	COL_NODE *pTemp = NULL;
	TBOOL bNew = TRUE;
	
	while (*pSrc!=0) 
	{
		if(bNew)
		{
			COL_NODE *p = Tools_Malloc(sizeof(COL_NODE));
			p->text = pSrc;
			if(!pNode)
			{
				pNode = p;
			}
			else
			{
				pTemp->next = p;
			}
			pTemp = p;
			bNew = FALSE;
		}
		
		if(*pSrc==c)
		{
			*pSrc=0x00;
			bNew = TRUE;
		}
		pSrc++;
	}
	return pNode;
}

COL_NODE* StringSplitStr(char *pSrc, char *pStr)
{
	COL_NODE *pNode = NULL;
	COL_NODE *pTemp = NULL;
	TBOOL bNew = TRUE;
	
	while (*pSrc!=0) 
	{
		if(bNew)
		{
			COL_NODE *p = Tools_Malloc(sizeof(COL_NODE));
			p->text = pSrc;
			if(!pNode)
			{
				pNode = p;
			}
			else
			{
				pTemp->next = p;
			}
			pTemp = p;
			bNew = FALSE;
		}
		
		if(*pSrc==pStr[0])
		{
			char *p;
			char *p2;
			p = pSrc+1;
			p2 = pStr+1;
			while (*p==*p2 && *p!=0x00 && *p2!=0x00) {
				p++;
				p2++;
			}
			if (*p2==0x00) {
				int nLen = strlen(pStr);
				for (int i=0; i<nLen; i++) {
					*pSrc = 0x00;
					pSrc++;
				}
				pSrc--;
				//*p=0x00;
				bNew = TRUE;
			}
		}
		pSrc++;
	}
	return pNode;
}

ROW_NODE* StringSplitRowCol(char *pSrc, char r, char c)
{
	ROW_NODE *pRow = NULL;
	ROW_NODE *pTempRow = NULL;
	//拆分成行
	COL_NODE *pRowCol;
	COL_NODE *pRowColT;
	
	int nLen;
	char *buf;
	nLen = strlen(pSrc);
	
	if (nLen<=0) {
		return NULL;
	}
	buf = Tools_Malloc(nLen+2);
	
	memcpy(buf, pSrc, nLen);
	
	pRowColT = pRowCol = StringSplit(buf, r);
	while (pRowCol) 
	{
		ROW_NODE *p = Tools_Malloc(sizeof(ROW_NODE));
		//拆分成列
		p->node = StringSplit(pRowCol->text, c);
		if(!pRow)
		{
			pRow = p;
		}
		else
		{
			pTempRow->next = p;
		}
		pTempRow = p;
		pRowCol = pRowCol->next;
	}
	FreeColNode(&pRowColT);
	pRow->buf = buf;
	return pRow;
}

ROW_NODE* StringSplitRowColStr(char *pSrc, char *pRStr, char *pCStr)
{
	ROW_NODE *pRow = NULL;
	ROW_NODE *pTempRow = NULL;
	//拆分成行
	COL_NODE *pRowCol;
	COL_NODE *pRowColT;
	
	int nLen;
	char *buf;
	nLen = strlen(pSrc);
	
	if (nLen<=0) {
		return NULL;
	}
	buf = Tools_Malloc(nLen+2);
	
	memcpy(buf, pSrc, nLen);
	
	pRowColT = pRowCol = StringSplitStr(pSrc, pRStr);
	while (pRowCol) 
	{
		ROW_NODE *p = Tools_Malloc(sizeof(ROW_NODE));
		//拆分成列
		p->node = StringSplitStr(pRowCol->text, pCStr);
		if(!pRow)
		{
			pRow = p;
		}
		else
		{
			pTempRow->next = p;
		}
		pTempRow = p;
		pRowCol = pRowCol->next;
	}
	FreeColNode(&pRowColT);
	pRow->buf = buf;
	return pRow;
}

int GetColCount(COL_NODE *pNode)
{
	int nCount=0;
	while (pNode) {
		nCount++;
		pNode = pNode->next;
	}
	return nCount;
}

int GetRowCount(ROW_NODE *pNode)
{
	int nCount=0;
	while (pNode) {
		nCount++;
		pNode = pNode->next;
	}
	return nCount;
}

int Utf8ToUnicodeLength(char *pSrc, int nLen)
{
	int i = 0;
	int j = 0;
	while (i < nLen) {
		// 1110xxxx 10xxxxxx 10xxxxxx
		if ((pSrc[i] & MASK3BYTES) == MASK3BYTES) {
			i += 3;
		}
		// 110xxxxx 10xxxxxx
		else if ((pSrc[i] & MASK2BYTES) == MASK2BYTES) {
			i += 2;
		}
		// 0xxxxxxx
		else if ((u_byte)pSrc[i] < MASKBYTE) {
			i += 1;
		}
		j+=2;
	}
	return j;
}

TBOOL IsNumber(char *pSrc)
{
	char *p = pSrc;
	TBOOL b = TRUE;
	while (p) {
		// 1110xxxx 10xxxxxx 10xxxxxx
		if ((p[0] & MASK3BYTES) == MASK3BYTES) {
			b = FALSE;
			break;
		}
		// 110xxxxx 10xxxxxx
		else if ((p[0] & MASK2BYTES) == MASK2BYTES) {
			b = FALSE;
			break;
		}
		// 0xxxxxxx
		else if ((u_byte)p[0] < MASKBYTE) {
			if ((p[0]>=0x30 && p[0]<=0x38) || p[0]==','|| p[0]=='.')
			{
				p += 1;
			}
			else
			{
				b = FALSE;
				break;
			}
		}
		
	}
	return b;
}

void Utf8ToUnicode(char *pSrc, int nLen, char *pDes)
{
	int i = 0;
	int j = 0;
	int nUnicode;
	while (i < nLen) {
		nUnicode = 0;
		// 1110xxxx 10xxxxxx 10xxxxxx
		if ((pSrc[i] & MASK3BYTES) == MASK3BYTES) {
			nUnicode = ((pSrc[i] & 0x0F) << 12) | ((pSrc[i + 1] & MASKBITS) << 6) | (pSrc[i + 2] & MASKBITS);
			i += 3;
		}
		// 110xxxxx 10xxxxxx
		else if ((pSrc[i] & MASK2BYTES) == MASK2BYTES) {
			nUnicode = ((pSrc[i] & 0x1F) << 6) | (pSrc[i + 1] & MASKBITS);
			i += 2;
		}
		// 0xxxxxxx
		else if ((u_byte)pSrc[i] < MASKBYTE) {
			nUnicode = pSrc[i];
			i += 1;
		}
		
		pDes[j++] = (nUnicode & 0xFF);
		pDes[j++] = ((nUnicode >> 8) & 0xFF);
	}
}


char* Utf8ToUnicodeEx(char *pSrc)
{
	int nUtf8Len;
	int nUnicLen;
	char *pUnicDes;
	if (!pSrc)
	{
		return NULL;
	}
	
	nUtf8Len = strlen(pSrc);
	nUnicLen = Utf8ToUnicodeLength(pSrc, nUtf8Len);
	pUnicDes = (char*)Tools_Malloc(nUnicLen+2);
	Utf8ToUnicode(pSrc, nUtf8Len, pUnicDes);
	return pUnicDes;
}

int UnicodeToUtf8Length(char *pSrc, int nLen)
{
	int i = 0;
	int j = 0;
	int nCode;
	while (i < nLen) {
		nCode = (pSrc[i] & 0xFF) | ((pSrc[i + 1] & 0xFF) << 8);
		// 0xxxxxxx
		if (nCode < 0x80) {
			j++;
		}
		// 110xxxxx 10xxxxxx
		else if (nCode < 0x800) {
			j+=2;
		}
		// 1110xxxx 10xxxxxx 10xxxxxx
		else if (nCode < 0x10000) {
			j+=3;
		}
		i += 2;
	}
	return j;
}


void UnicodeToUtf8(char *pSrc, int nLen, char *pDes)
{
	int i = 0;
	int j = 0;
	int nCode;
	while (i < nLen) {
		nCode = (pSrc[i] & 0xFF) | ((pSrc[i + 1] & 0xFF) << 8);
		// 0xxxxxxx
		if (nCode < 0x80) {
			pDes[j++] = nCode;
		}
		// 110xxxxx 10xxxxxx
		else if (nCode < 0x800) {
			pDes[j++] = (MASK2BYTES | nCode >> 6);
			pDes[j++] = (MASKBYTE | nCode & MASKBITS);
		}
		// 1110xxxx 10xxxxxx 10xxxxxx
		else if (nCode < 0x10000) {
			pDes[j++] = (MASK3BYTES | nCode >> 12);
			pDes[j++] = (MASKBYTE | nCode >> 6 & MASKBITS);
			pDes[j++] = (MASKBYTE | nCode & MASKBITS);
		}
		i += 2;
	}
}

char* UnicodeToUtf8Ex(char *pSrc)
{
	int nUtf8Len;
	int nUnicLen;
	char *pUtf8Des;
	if (!pSrc)
	{
		return NULL;
	}
	nUnicLen = GetUnicodeStringLength(pSrc);
	nUtf8Len = UnicodeToUtf8Length(pSrc, nUnicLen<<1);
	pUtf8Des = (char*)Tools_Malloc(nUtf8Len+2);
	UnicodeToUtf8(pSrc, nUnicLen<<1, pUtf8Des);
	return pUtf8Des;
}

int GetUnicodeStringLength(char *pSrc)
{
	int nLen;
	char *pPos;
	if (!pSrc)
	{
		return -1;
	}
	pPos = pSrc;
	while(pPos[0]!=0x00 || pPos[1]!=0x00)
	{
		pPos+=2;
		nLen++;
	}
	return nLen;
}

void CharToHex(char *pSrc, int nLen, char *pDes)
{
	char hexDigit[] = "0123456789ABCDEF";
	int i;
	int j = 0;
	for(i=0; i<nLen; i++)
	{
		//高4位
		pDes[j++] = hexDigit[(pSrc[i] >> 4) & 0x0F];
		//低4位
		pDes[j++] = hexDigit[pSrc[i] & 0x0F];
	}
}

int HexToColor(char *pSrc)
{
	int i; 
	int nLen = 6;
	int j = 1;
	
	char pDes[8];
	memset(pDes, 0, 8);
	
	for(i=0; i<nLen; i++)
	{  
		//高4位
		if(pSrc[i]>=0x30 && pSrc[i]<=0x39)
		{
			pDes[j] = (pSrc[i]-0x30)<<4;
		}
		else
		{
			pDes[j] = (pSrc[i]-0x41+10)<<4;
		}
		
		//低4位
		i++;
		if(pSrc[i]>=0x30 && pSrc[i]<=0x39)
		{
			pDes[j++] |= (pSrc[i]-0x30);
		}
		else
		{
			pDes[j++] |= (pSrc[i]-0x41+10);
		}
	}
	return BytesToInt(pDes, 0);
	
}

long64 BytesToLong64(char *pSrc, int nPos)
{
	long64 lLong;
	lLong = (((long64)(char)pSrc[nPos++])&0xFF)<<56;
	lLong += (((long64)(char)pSrc[nPos++])&0xFF)<<48;
	lLong += (((long64)(char)pSrc[nPos++])&0xFF)<<40;
	lLong += (((long64)(char)pSrc[nPos++])&0xFF)<<32;
	lLong += (((long64)(char)pSrc[nPos++])&0xFF)<<24;
	lLong += (((long64)(char)pSrc[nPos++])&0xFF)<<16;
	lLong += (((long64)(char)pSrc[nPos++])&0xFF)<<8;
	lLong += (((long64)(char)pSrc[nPos++])&0xFF);
	return lLong;
}

void Long64ToBytes(long64 n, char *pDst)
{
	pDst[0] = (n>>56)&0xFF;
	pDst[1] = (n>>48)&0xFF;
	pDst[2] = (n>>40)&0xFF;
	pDst[3] = (n>>32)&0xFF;
	pDst[4] = (n>>24)&0xFF;
	pDst[5] = (n>>16)&0xFF;
	pDst[6] = (n>>8)&0xFF;
	pDst[7] = n&0xFF;
}

long64 StringToLong(char *pSrc, int nLen)
{
	long64 sum;
	sum = 0;
	int nPos = 0;
	while(pSrc[nPos]!=0x00 && nPos<nLen)
	{
		sum *=10;
		sum += (pSrc[nPos++]-48);
	}
   	return sum;
}

u_int ELFHash(char* str)
{  
	unsigned int hash = 0;
    int i;
    for (i=0; *str; i++)
    {
        if ((i & 1) == 0)
        {
            hash ^= ((hash << 7) ^ (*str++) ^ (hash >> 3));
        }
        else
        {
            hash ^= (~((hash << 11) ^ (*str++) ^ (hash >> 5)));
        }
    }
    return (hash & 0x7FFFFFFF);
}

void MOVEMEM(char *pSrc, char *pDsc, int nLen)
{
	if(!pSrc || !pDsc || nLen<=0)
	{
		return;
	}
	int nPos = 0;
	char *pDD;
	char *pSS;
	pDD = pDsc + nLen-1;
	pSS = pSrc + nLen-1;
	while(nPos++<nLen)
	{	
		*pDD=*pSS;
    *pSS=0x00;
		pDD--;
		pSS--;
	}
}

long64 DateTimeInt2Long(int intDateTime)
{
	
	long64 minute=intDateTime & 0x3F;
	long64 hour=(intDateTime>>6) & 0x1F;
	long64 day=(intDateTime>>11) & 0x1F;
	long64 month=(intDateTime>>16) & 0x0F;
	long64 year=(intDateTime>>20) & 0x0FFF;
	
	long64 longDateTime=year*10000000000L+month*100000000L+day*1000000L+hour*10000L+minute*100L;
	return longDateTime;
}

void HexToChar(char *pSrc, int nLen, char *pDes)
{
    int i; 
    int j = 0;
    for(i=0; i<nLen; i++)
    {  
        //低4字节
        if(pSrc[i]>=0x30 && pSrc[i]<=0x39)
        {
            pDes[j] = (pSrc[i]-0x30)<<4;
        }
        else
        {
            pDes[j] = (pSrc[i]-0x61+10)<<4;
        }
		
        //高4字节
        i++;
        if(pSrc[i]>=0x30 && pSrc[i]<=0x39)
        {
            pDes[j++] |= (pSrc[i]-0x30);
        }
        else
        {
            pDes[j++] |= (pSrc[i]-0x61+10);
        }
    }
}

//数据结构，不定长 1(后续标志)+1(正负号)+6(数据) + N[每扩展字节为1(后续标志)+7(数据)]
void readInt(void *p, int *n, int *nc)
{
//    char *pBuf;
//    int pn=0;
//    pBuf = p;
//    pn = (pBuf[0]&0x40);
//    *n = (pBuf[0]&0x3F);
//    *nc = 1;
//    if((pBuf[0]&0x80)==0x00)
//    {
//        //有下一字节
//        pBuf++;
//        while((pBuf[0]&0x80)==0x00)
//        {
//            *nc+=1;
//            //有下一个
//            *n = (*n<<7)|(pBuf[0]&0x7F);
//            pBuf++;
//        }
//        *nc+=1;
//        *n = (*n<<7)|(pBuf[0]&0x7F);
//    }
//    pBuf = p;
//    if(pn==0x40)
//    {
//        //负数
//        *n = 0-*n;
//    }
	
	
	
	int val=0;
	char b;
	int ind=0;
	char *pBuf = p;
	do{
		b = pBuf[0];
		if(ind==0 && (b & 0x40)!=0){
			val=0xffffffff;
		}
		ind++;
		val = (val<<7) | (b & 0x7f);
		pBuf++;
		(*nc)++;
	}
	while( (b&0x80)==0);
	
	*n = val;
	
}

//数据结构，不定长 1(后续标志)+1(正负号)+6(数据) + N[每扩展字节为1(后续标志)+7(数据)]
void readLong(void *p, long long *n, int *nc)
{
//    char *pBuf;
//    int pn=0;
//    pBuf = p;
//    pn = (pBuf[0]&0x40);
//    *n = (pBuf[0]&0x3F);
//    *nc = 1;
//    if((pBuf[0]&0x80)==0x00)
//    {
//        //有下一字节
//        pBuf++;
//        while((pBuf[0]&0x80)==0x00)
//        {
//            *nc+=1;
//            //有下一个
//            *n = (*n<<7)|(pBuf[0]&0x7F);
//            pBuf++;
//        }
//        *nc+=1;
//        *n = (*n<<7)|(pBuf[0]&0x7F);
//    }
//    pBuf = p;
//    if(pn==0x40)
//    {
//        //负数
//        *n = 0-*n;
//    }
	
	long long val=0;
	char b;
	int ind=0;
	char *pBuf = p;
	do{
		b = pBuf[0];
		if(ind==0 && (b & 0x40)!=0){
			val=0xffffffffffffffffL;
		}
		ind++;
		val = (val<<7) | (b & 0x7f);
		pBuf++;
		(*nc)++;
	}
	while( (b&0x80)==0);
	
	*n = val;
}

//数据结构，24位，结构为4(10的n次方)+1(符号位)+19(数据位)
void readRLong(void *p, long long *l)
{
    char *pBuf;
    int nR = 0;
    pBuf = p;
    
    //10的n次方
    nR = (pBuf[0]>>4)&0xF;
    
    //数值
    *l = ((pBuf[0]&0x07)<<16)|(((pBuf[1]&0xFF)<<8))|(*l|(pBuf[2]&0xFF));
    
    //*10的次方，pow需要math.h，计算x的y次方
    *l = (*l)*pow(10, nR);
    
    //符号位
    if((pBuf[0]&0x08)==0x08)
    {
        //负数
        *l = 0-*l;
    }
}

